/**
 * Created by Sxd on 2014/10/10.
 */

var xinyou = xinyou || {};
var singleGame = singleGame || false;
/**
 * @class
 * @extends cc.Class
 * @property isCoprocceor 暂停消息派发
 */
var GameFrame = cc.Class.extend(/** @lends GameFrame */{

    /**
     * 登陆返回的自己信息
     * @type vo.LoginInfo
     */
    meFromLogin: vo.LoginInfo,
    /**
     * 游戏服务器上自己的信息
     * @type vo.UserItem
     */
    me: null,
    gameStatus: 0,
    ctor: function () {
        cc.defineGetterSetter(this, 'isCoprocceor', this.isCoprocceorGetter, this.isCoprocceorSetter);
    },
    /**
     * 自己一桌的用户列表
     * @type {vo.UserItem[]}
     */
    userList: [],

    isMeDataSended: false,

    /**
     * @private
     */
    _isCoprocceor: true,
    _eventCacheList: [],

    /**
     * @param {number} mainCMD
     * @param {number} subCMD
     * @param {xinyou.Packet} byData
     */
//    onAllMessage:function (mainCMD, subCMD, byData) {
//        if ((mainCMD == 0) && (subCMD == 1)) {
//            //xinyou.log('收到心跳包');
//            this._sendHeartBeat(byData);
//            return;
//        }
//
//        this.dispatchEvent(GameFrameEvent.GAME_ALL_MESSAGE, {mid:mainCMD, sid:subCMD, data:byData});
//
//    },

    /**
     * 收到场景消息
     * @param gameState
     * @param isLookonOther
     * @param {xinyou.Packet} byData
     */
    onGameSceneMessage: function (gameState, isLookonOther, byData) {
        if (!this.isMeDataSended) {
            this._isCoprocceor = false;
        }
        this.dispatchEvent(GameFrameEvent.GAME_SCENE_MESSAGE, {
            gameState: gameState,
            isLook: isLookonOther,
            data: byData
        });

    },

    /**
     * 收到框架消息
     * @param {number} subCMD
     * @param {xinyou.Packet} byData
     */
    onFrameMessage: function (subCMD, byData) {
        this.dispatchEvent(GameFrameEvent.GAME_FRAME_MESSAGE, {id: subCMD, data: byData});
    },

    /**
     * 收到单款消息
     * @param {number} subCMD
     * @param {xinyou.Packet} byData
     */
    onGameMessage: function (subCMD, byData) {
        if (!this.isMeDataSended) {
            this._isCoprocceor = false;
        }
        this.dispatchEvent(GameFrameEvent.GAME_MESSAGE, {id: subCMD, data: byData});
    },

    /**
     * 收到用户消息
     * @param {number} subCMD
     * @param {xinyou.Packet} byData
     */
    onGameUserMessage: function (subCMD, byData) {

    },

    toInRoom: function (byData) {
        gpNamespace.roomType = byData.readByte();
        gpNamespace.subRoom = byData.readByte(); //1-6
        gpNamespace.biXia = byData.readInt();
        gpNamespace.difen = byData.readInt();
        gpNamespace.roomLimitScore = byData.readInt();
        gpNamespace.chouShui = byData.readInt();
        gpNamespace.currentCount = byData.readInt();

        cc.log("进入房间的低分：" + gpNamespace.difen);
        cc.log("gpNamespace.subRoom:" + gpNamespace.subRoom);

        currentNetManager.inRoom();
    },

    onGameRoomLogin: function (subCMD, byData, checkCode) {
        switch (subCMD) {
            case NetConstant.SUB_GS_LOGON_INROOM:
                cc.log("ongameroomlogin>>>>>>>>>>>>>>>>>>>>:"+checkCode);
                if (checkCode == 1) {
                    this.toInRoom(byData);

                    break;
                }

                var runningScene = cc.director.getRunningScene();
                var juhua = runningScene.getChildByName(tyNamespace.Juhua);
                juhua && juhua.removeFromParent(true);

                currentNetManager.removeMyListeners();

                currentNetManager.jumpNoGold();

                break;

            case NetConstant.SUB_GS_SIT_CHAIR:
                currentNetManager.sitDown(checkCode);

                break;

            case NetConstant.STANDUP:
                currentNetManager.standUp(checkCode);

                break;

            case NetConstant.SUB_GS_LEAVETABLE:
                if (checkCode == 1)
                    currentNetManager.onUserLeave(byData);

                break;

            case NetConstant.SUB_GS_LEAVEROOM:
                if (currentNetManager.baoMingLayer) {
                    if (checkCode == 1) {
                        currentNetManager.cancelBaoMing();

                        break;
                    }

                    gpNamespace.showDialog("人满比赛已开始！");
                }

                break;

            case NetConstant.CREATETABLE:
                var zhao = cc.director.getRunningScene().getChildByName("zhao");
                if (zhao)
                    zhao.removeFromParent(true);

                if (checkCode != 1) {
                    gpNamespace.showDialog("创建失败！");
                    break;
                }

                this.toInRoom(byData);

                break;

            case NetConstant.TABLELIST:
                currentNetManager.showTalbeList(byData, checkCode);

                break;

            case NetConstant.INTABLE:
                var zhao = cc.director.getRunningScene().getChildByName("zhao");
                if (zhao)
                    zhao.removeFromParent(true);

                if (checkCode != 1) {
                    gpNamespace.showDialog("房间不存在或者房间已满！");

                    var middleLayer = cc.director.getRunningScene().getChildByName("middleLayer");
                    if (middleLayer) {
                        middleLayer.showTalbeList();
                    }

                    break;
                }

                this.toInRoom(byData);

                break;

            default:
                break;
        }
    },

    /**
     * 发送框架消息
     * @param subCMD 子消息号
     * @param {xinyou.ByteArray} byData 消息体
     */
    sendGameMessage: function (subCMD, byData) {
        xinyou.netManager.sendGameMessage(subCMD, byData);
    },

    /**
     * 发送框架消息
     * @param subCMD 子消息号
     * @param {xinyou.ByteArray} byData 消息体
     */
    sendFrameMessage: function (subCMD, byData) {
        xinyou.netManager.sendFrameMessage(subCMD, byData);
    },

    /**
     * 发送自定义消息
     * @param mainCMD {number} 大消息号
     * @param subCMD {number} 小消息号
     * @param [byData] {xinyou.ByteArray} 结构体
     */
    sendCustomMessage: function (mainCMD, subCMD, byData) {
        xinyou.netManager.sendCustomMessage(mainCMD, subCMD, byData);
    },

    /**
     * @param {netStruct.LogonSuccess} msg
     */
    onSUB_GS_LOGON_SUCCESS: function (msg) {
        xinyou.log('登陆成功');
        this.dispatchEvent(NetEvent.GS_LogonSuccess, msg);
    },

    /**
     * @param {netStruct.LogonFail} msg
     */
    onSUB_GS_LOGON_FAIL: function (msg) {
        xinyou.log('登陆失败 错误信息：%d  %s', msg.errorCode, msg.errorDesc);
        this.dispatchEvent(NetEvent.GS_LogonFail, msg);
    },

    /**
     * @param {netStruct.Register} msg
     */
    onSUB_GS_REGISTER: function (msg) {
        xinyou.log("注册");
        this.dispatchEvent(NetEvent.GS_Register, msg);
    },

    /**
     * @param {netStruct.Login} msg
     */
    onSUB_GS_LOGIN: function (msg) {
        xinyou.log("登陆");
        this.dispatchEvent(NetEvent.GS_Login, msg);
    },

    /**
     * @param {netStruct.Account} msg
     */
    onSUB_GS_ACCOUNT: function (msg) {
        xinyou.log("完善账号或修改密码");
        this.dispatchEvent(NetEvent.GS_Account, msg);
    },

    /**
     * @param {netStruct.ChangeInfo} msg
     */
    onSUB_GS_CHANGE_INFO: function (msg) {
        xinyou.log("修改个人信息");
        this.dispatchEvent(NetEvent.GS_ChangeInfo, msg);
    },

    /**
     * 使用道具
     */
    onSUB_GS_USEPROP: function (msg) {
        xinyou.log("使用道具");
        this.dispatchEvent(NetEvent.GS_UserProp, msg);
    },

    onSUB_GS_BEFOREUSEPROP: function (msg) {
        xinyou.log("使用道具前");
        this.dispatchEvent(NetEvent.GS_BeforeUserProp, msg);
    },

    /**
     * 使用喇叭
     */
    onSUB_GS_USELABA: function (msg) {
        xinyou.log("使用喇叭");
        this.dispatchEvent(NetEvent.GS_UseLaba, msg);
    },

    onSUB_GS_POKE_COUNT: function (msg) {
        xinyou.log("使用记牌器");
        this.dispatchEvent(NetEvent.GS_PokeCount, msg);
    },

    onSUB_GS_USEPROPRESULT: function (msg) {
        xinyou.log("使用道具结果");
        this.dispatchEvent(NetEvent.GS_UsePropResult, msg);
    },

    /**
     * 商城标签
     */
    onSUB_GS_MARKETITEM: function (msg) {
        xinyou.log("商城显示");
        this.dispatchEvent(NetEvent.GS_MarketItem, msg);
    },

    /**
     * 商城购买  第四页
     */
    onSUB_GS_MARKETBUYCZ: function (msg) {
        xinyou.log("商城购买 第四页");
        this.dispatchEvent(NetEvent.GS_MarketBuyCz, msg);
    },

    /**
     * 商城购买  第二页
     */
    onSUB_GS_MARKETBUYJB: function (msg) {
        xinyou.log("商城购买 第二页");
        this.dispatchEvent(NetEvent.GS_MarketBuyJb, msg);
    },

    /**
     * 商城购买  第三页
     */
    onSUB_GS_MARKETBUYDJ: function (msg) {
        xinyou.log("商城购买 第三页");
        this.dispatchEvent(NetEvent.GS_MarketBuyDj, msg);
    },

    /**
     * 商城购买  第一页
     */
    onSUB_GS_MARKETBUYSW: function (msg) {
        xinyou.log("商城购买 第一页");
        this.dispatchEvent(NetEvent.GS_MarketBuySw, msg);
    },

    /**
     * 商城物品详细信息
     */
    onSUB_GS_GOODINFO: function (msg) {
        xinyou.log("商城物品详细信息");
        this.dispatchEvent(NetEvent.GS_GoodInfo, msg);
    },

    /**
     * 个人信息 我的道具
     */
    onSUB_GS_MYRPOP: function (msg) {
        xinyou.log("个人信息 我的道具");
        this.dispatchEvent(NetEvent.GS_MyProp, msg);
    },

    /**
     * 商品支付信息
     */
    onSUB_GS_PAYINFO: function (msg) {
        xinyou.log("商品支付信息");
        this.dispatchEvent(NetEvent.GS_PayInfo, msg);
    },

    /**
     * 商品支付结果
     */
    onSUB_GS_PAYRESULT: function (msg) {
        xinyou.log("商品支付结果");
        this.dispatchEvent(NetEvent.GS_PayResult, msg);
    },

    onSUB_GS_MYSIGN: function (msg) {
        xinyou.log("签到页");
        this.dispatchEvent(NetEvent.GS_Sign, msg);
    },

    onSUB_GS_SETSIGN: function (msg) {
        xinyou.log("签到按钮");
        this.dispatchEvent(NetEvent.GS_SetSign, msg);
    },

    onSUB_GS_GETSIGN: function (msg) {
        xinyou.log("领取签到奖励");
        this.dispatchEvent(NetEvent.GS_GetSign, msg);
    },

    onSUB_GS_RANK: function (msg) {
        xinyou.log("排行榜");
        this.dispatchEvent(NetEvent.GS_Rank, msg);
    },

    onSUB_GS_MISSION: function (msg) {
        xinyou.log("任务");
        this.dispatchEvent(NetEvent.GS_Mission, msg);
    },

    onSUB_GS_INNERMISSION: function (msg) {
        xinyou.log("内部任务");
        this.dispatchEvent(NetEvent.GS_InnerMission, msg);
    },

    onSUB_GS_MISSIONREWARD: function (msg) {
        xinyou.log("任务奖励");
        this.dispatchEvent(NetEvent.GS_MissionReward, msg);
    },

    onSUB_GS_GAMEMISSIONREWARD: function (msg) {
        xinyou.log("游戏任务奖励");
        this.dispatchEvent(NetEvent.GS_GameMissionReward, msg);
    },

    onSUB_GS_FRIEND: function (msg) {
        xinyou.log("好友");
        this.dispatchEvent(NetEvent.GS_Friend, msg);
    },

    onSUB_GS_EDITFRIEND: function (msg) {
        xinyou.log("编辑好友");
        this.dispatchEvent(NetEvent.GS_EditFriend, msg);
    },

    onSUB_GS_FRIENDVERIFY: function (msg) {
        xinyou.log("好友验证列表");
        this.dispatchEvent(NetEvent.GS_FriendVerify, msg);
    },

    onSUB_GS_FRIENDRESPONSE: function (msg) {
        xinyou.log("好友验证");
        this.dispatchEvent(NetEvent.GS_FriendResponse, msg);
    },

    onSUB_GS_SEARCHFRIEND: function (msg) {
        xinyou.log("搜索好友");
        this.dispatchEvent(NetEvent.GS_SearchFriend, msg);
    },

    onSUB_GS_TALK: function (msg) {
        xinyou.log("社交聊天");
        this.dispatchEvent(NetEvent.GS_Talk, msg);
    },

    onSUB_GS_HISTORYTALK: function (msg) {
        xinyou.log("历史聊天");
        this.dispatchEvent(NetEvent.GS_HistoryTalk, msg);
    },

    onSUB_GS_HISTORYLABA: function (msg) {
        xinyou.log("历史喇叭聊天");
        this.dispatchEvent(NetEvent.GS_HistoryLaba, msg);
    },

    onSUB_GS_MAILLIST: function (msg) {
        xinyou.log("邮件列表");
        this.dispatchEvent(NetEvent.GS_MailList, msg);
    },

    onSUB_GS_MAILEDIT: function (msg) {
        xinyou.log("邮件编辑");
        this.dispatchEvent(NetEvent.GS_MailEdit, msg);
    },

    onSUB_GS_MAILINFO: function (msg) {
        xinyou.log("邮件详细信息");
        this.dispatchEvent(NetEvent.GS_MailInfo, msg);
    },

    onSUB_GS_SENDMAIL: function (msg) {
        xinyou.log("发送邮件");
        this.dispatchEvent(NetEvent.GS_SendMail, msg);
    },

    onSUB_GS_EGG: function (msg) {
        xinyou.log("砸金蛋");
        this.dispatchEvent(NetEvent.GS_Egg, msg);
    },

    onSUB_GS_GOLDEGG: function (msg) {
        xinyou.log("收费砸金蛋");
        this.dispatchEvent(NetEvent.GS_GoldEgg, msg);
    },

    onSUB_GS_CAN_EGG: function (msg) {
        xinyou.log("能否砸金蛋");
        this.dispatchEvent(NetEvent.GS_CanEgg, msg);
    },

    onSUB_GS_EGG_NAME_LIST: function (msg) {
        xinyou.log("砸金蛋获奖名单");
        this.dispatchEvent(NetEvent.GS_EggNameList, msg);
    },

    onSUB_GS_POCHAN: function (msg) {
        xinyou.log("破产补助");
        this.dispatchEvent(NetEvent.GS_Pochan, msg)
    },

    onSUB_GS_RUCHANG: function (msg) {
        xinyou.log("入场信息");
        this.dispatchEvent(NetEvent.GS_Ruchang, msg)
    },

    onSUB_GS_USERTALK: function (msg) {
        xinyou.log("内部聊天");
        this.dispatchEvent(NetEvent.GS_UserTalk, msg)
    },

    onSUB_GS_INNER_USERINFO: function (msg) {
        xinyou.log("内部个人信息");
        this.dispatchEvent(NetEvent.GS_InnerUserInfo, msg)
    },

    onSUB_GS_GAME_NOTICE: function (msg) {
        xinyou.log("游戏提示");
        this.dispatchEvent(NetEvent.GS_GameNotice, msg)
    },

    onSUB_GS_RESTTIME: function (msg) {
        xinyou.log("倒计时");
        this.dispatchEvent(NetEvent.GS_RestTime, msg)
    },

    onSUB_GS_GONGGAO: function (msg) {
        xinyou.log("公告");
        cc.log("gonggao>>>>>");
        this.dispatchEvent(NetEvent.GS_Gonggao, msg)
    },

    onSUB_GS_GETQQ: function (msg) {
        xinyou.log("获得群号");
        this.dispatchEvent(NetEvent.GS_GetQQ, msg)
    },

    onSUB_GS_GETWX: function (msg) {
        xinyou.log("获得微信分享");
        this.dispatchEvent(NetEvent.GS_GetWX, msg)
    },

    onSUB_GS_JIHUO: function (msg) {
        xinyou.log("激活");
        this.dispatchEvent(NetEvent.GS_Jihuo, msg)
    },

    onSUB_GS_GETVIPDAYS: function (msg) {
        xinyou.log("获得VIP天数");
        this.dispatchEvent(NetEvent.GS_GetVIPDays, msg)
    },

    onSUB_GS_GAME_KICK: function (msg) {
        xinyou.log("游戏踢人");
        this.dispatchEvent(NetEvent.GS_GameKick, msg)
    },

    onSUB_GS_GAME_CHEAT: function (msg) {
        xinyou.log("举报作弊");
        this.dispatchEvent(NetEvent.GS_GameCheat, msg)
    },

    ///**
    // * @param {netStruct.QuickCharge} msg
    // */
    //onSUB_GS_CHARGE: function (msg) {
    //    xinyou.log("快速充值");
    //    this.dispatchEvent(NetEvent.GS_QuickCharge, msg);
    //},
    //
    ///**
    // * @param {netStruct.GoldExchange} msg
    // */
    //onSUB_GS_GOLDEXCHANGE: function (msg) {
    //    xinyou.log("游戏币兑换");
    //    this.dispatchEvent(NetEvent.GS_GoldExchange, msg);
    //},
    //
    ///**
    // * @param {netStruct.PropExchange} msg
    // */
    //onSUB_GS_PROPEXCHANGE: function (msg) {
    //    xinyou.log("道具兑换");
    //    this.dispatchEvent(NetEvent.GS_PropExchange, msg);
    //},
    //
    ///**
    // * @param {netStruct.PhysicalExchange} msg
    // */
    //onSUB_GS_PHYSICALEXCHANGE: function (msg) {
    //    xinyou.log("实物兑换");
    //    this.dispatchEvent(NetEvent.GS_PhysicalExchange, msg);
    //},

    /**
     * @param {netStruct.LogonFinish} msg
     */
    onSUB_GS_LOGON_FINISH: function (msg) {
        xinyou.log('登陆完成');
        this.dispatchEvent(NetEvent.GS_LogonFinish, msg);
    },

    /**
     * @param {netStruct.ServerInfo} msg
     */
    onSUB_GS_SERVER_INFO: function (msg) {
        xinyou.log('获取服务器信息');
        xinyou.roomManager.init(msg);
        this.dispatchEvent(NetEvent.GS_ServerInfo, msg);
    },

    /**
     * @param {netStruct.GetTableListInfo} msg
     */
    onSUB_GS_TABLE_INFO: function (msg) {
        xinyou.log('获取桌子信息');
        xinyou.roomManager.initTableInfo(msg);
        this.dispatchEvent(NetEvent.GS_GetTableListInfo, msg);
    },

    /**
     * @param {netStruct.TableStatus} msg
     */
    onSUB_GS_TABLE_STATUS: function (msg) {
        if ((!xinyou.roomManager.isRandomAssignRoom) && (!xinyou.roomManager.isMatchRoom)) {
            xinyou.roomManager.updateTableStatus(msg);
        }
        this.dispatchEvent(NetEvent.GS_TableStatus, msg);
    },

    /**
     * @param {netStruct.SystemNotice} msg
     */
    onSUB_GS_SYSMESSAGE: function (msg) {
        this.dispatchEvent(NetEvent.GS_SystemNotice, msg);
    },

    /**
     * @param {netStruct.GetUserItem} msg
     */
    onSUB_GS_USER_COME: function (msg) {
        xinyou.roomManager.addUser(msg.userList);
        this.dispatchEvent(NetEvent.GS_GetUserItem, msg);
    },

    /**
     * @param {netStruct.UserBannedStatus} msg
     */
    onSUB_GS_USER_BANNED_STATUS: function (msg) {
        this.dispatchEvent(NetEvent.GS_UserBannedStatus, msg);
    },

    /**
     * @param {netStruct.UserSitFailed} msg
     */
    onSUB_GS_USER_SIT_FAILED: function (msg) {
        this.dispatchEvent(NetEvent.GS_UserSitFailed, msg);
    },

    /**
     * @param {netStruct.UserStatus} msg
     */
    onSUB_GS_USER_STATUS: function (msg) {
        xinyou.roomManager.updateUserStatus(msg);
        this.dispatchEvent(NetEvent.GS_UserStatusChanged, msg);
    },

    /**
     * @param {netStruct.UserScoreMSG} msg
     */
    onSUB_GS_USER_SCORE: function (msg) {
        xinyou.roomManager.updateScore(msg);
        this.dispatchEvent(NetEvent.GS_UserScoreChanged, msg);
    },

    /**
     * @param {netStruct.OnlineCntInfoMSG} msg
     */
    onSUB_GS_ONLINE_CNT_INFO: function (msg) {
        this.dispatchEvent(NetEvent.GS_OnlineCntInfoMSG, msg);
    },

    /**
     * @param {netStruct.GS_Message} msg
     */
    onSUB_GS_MESSAGE: function (msg) {
        this.dispatchEvent(NetEvent.GS_GameServerMessage, msg);
    },

    /**
     * @param {netStruct.UserChat} msg
     */
    onSUB_GS_USER_CHAT_INGAME: function (msg) {
        this.dispatchEvent(NetEvent.USER_CHAT_IN_GAME, msg);
    },

    /**
     * @param {netStruct.GS_EX_Option} msg
     */
    onSUB_GS_OPTION: function (msg) {
        xinyou.gameFrame.gameStatus = msg.cbGameStatus;

        xinyou.roomManager.dispatchUserJoinTable(this.me, this.me.wTableID, this.me.wChairID);

        var tableUser = xinyou.roomManager.getTableUser(this.me.wTableID);
        cc.log("tableUser++++++++++++++"+tableUser.length);
        if (tableUser) {
            var i;
            for (i = 0; i < tableUser.length; i++) {
                /**
                 * @type vo.UserItem
                 */
                var user = tableUser[i];
                if (!user || user.id == this.me.id)
                    continue;

                xinyou.roomManager.dispatchUserJoinTable(user, this.me.wTableID, i);
            }
        }

        this.dispatchEvent(NetEvent.GS_EX_Option, msg);
    },

    onSetMeUserData: function () {
        this.userList[this.me.wChairID] = this.me;
        this.isMeDataSended = true;
        this._isCoprocceor = true;
        this.dispatchEvent(GameFrameEvent.GAME_ME_ENTER, this.me);
    },

    /**
     * 新的用户进入
     * @param msg
     */
    onSUB_GS_USER_ENTER: function (msg) {
        cc.log("user orderIndex" + msg.wChairID + ",+++++++++++++++++name:" + msg.nickName);

        this.dispatchEvent(GameFrameEvent.GAME_USER_ENTER, msg);
    },

    /**
     * 用户进入消息
     * @param {vo.UserItem} user
     */
    onEnterUserItem: function (user) {
        this.userList[user.wChairID] = user;
        this.dispatchEvent(GameFrameEvent.GAME_USER_ENTER, user);
    },

    /**
     * 用户离开消息
     * @param {vo.UserItem} user
     */
    onLeftUserItem: function (user) {
        if (this.userList[user.wChairID]) {
            this.userList[user.wChairID] = null;
        }
        this.dispatchEvent(GameFrameEvent.GAME_USER_LEFT, user);
    },

    onUpdateUserItem: function (user) {
        this.userList[user.wChairID] = user;
        this.dispatchEvent(GameFrameEvent.GAME_USER_UPDATE, user);
    },

    /**
     * 发送心跳包
     * @param {xinyou.Packet} ba
     */
    _sendHeartBeat: function (ba) {
        ba.position = 0;
        xinyou.netManager.sendGameSocketMsg(0, 1, ba);
        //xinyou.log('发送心跳包');
    },

    isCoprocceorGetter: function () {
        return this._isCoprocceor;
    },

    isCoprocceorSetter: function (b) {
        this._isCoprocceor = b;
        if (b) {
            var _event;
            var i;
            for (i = 0; i < this._eventCacheList.length; i++) {
                _event = this._eventCacheList[i];
                cc.eventManager.dispatchEvent(_event);
            }
            this._eventCacheList.length = 0;
        }
    },

    dispatchEvent: function (eventName, data) {
        if (!eventName) throw '事件名有问题';

        var ev = new cc.EventCustom(eventName);
        ev.setUserData(data);
        cc.eventManager.dispatchEvent(ev);
    }

});

/**
 * @class
 * @extends cc.Class
 *
 * @property {Number} bytesAvailable
 * @property {ArrayBuffer} buffer
 */
xinyou.ByteArray = cc.Class.extend(/** @lends xinyou.ByteArray# */{
    ctor: function (buffer, length) {
        if (buffer) {
            this.dataView = new DataView(buffer);
            this.length = buffer.byteLength;
        } else {
            length = length || 8192;
            buffer = new ArrayBuffer(length);
            this.dataView = new DataView(buffer);
        }
    },

    /**
     * @type DataView
     */
    dataView: null,
    position: 0,
    length: 0,
    isLittleEndian: false,

    /**
     * @param {boolean} bool
     */
    writeBoolean: function (bool) {
        this.writeByte(bool ? 1 : 0);
    },

    writeByte: function (byte) {
        this.dataView.setInt8(this.position, ~~byte, this.isLittleEndian);
        this.position++;
        this._updateLength();
    },

    /**
     * 从bytes的offset处读取length个字节给自己
     * @param {xinyou.ByteArray} bytes
     * @param {number} [offset = 0]
     * @param {number} [length = bytes.bytesAvailable]
     */
    writeBytes: function (bytes, offset, length) {
        offset = offset || 0;
        var posOrg = bytes.position;
        bytes.position = offset;
        length = length || bytes.bytesAvailable;
        for (var i = 0; i < length; i++) {
            this.writeByte(bytes.readByte());
        }
        bytes.position = posOrg;
    },

    writeUnsignedByte: function (byte) {
        this.dataView.setUint8(this.position, (~~byte) & 0xff, this.isLittleEndian);
        this.position++;
        this._updateLength();
    },

    writeShort: function (byte) {
        this.dataView.setInt16(this.position, ~~byte, this.isLittleEndian);
        this.position += 2;
        this._updateLength();
    },

    writeUnsignedShort: function (byte) {
        this.dataView.setUint16(this.position, (~~byte) & 0xffff, this.isLittleEndian);
        this.position += 2;
        this._updateLength();
    },

    writeInt: function (byte) {
        this.dataView.setInt32(this.position, ~~byte, this.isLittleEndian);
        this.position += 4;
        this._updateLength();
    },

    writeUnsignedInt: function (byte) {
        this.dataView.setUint32(this.position, (~~byte) & 0xffffffff, this.isLittleEndian);
        this.position += 4;
        this._updateLength();
    },

    writeLong: function (byte) {
        this.writeByte(byte / 0x100000000000000);
        this.writeByte(byte / 0x1000000000000);
        this.writeByte(byte / 0x10000000000);
        this.writeByte(byte / 0x100000000);
        this.writeByte(byte / 0x1000000);
        this.writeByte(byte / 0x10000);
        this.writeByte(byte / 0x100);
        this.writeByte(byte % 0x100);
    },

    writeInt64: function (byte) {
        for (var i = 0; i < 8; i++) {
            var b = (Math.floor(byte / Math.pow(2, i * 8))) & 0xFF;
            this.writeByte(b);
        }
    },

    writeMyString: function (str) {
        this.writeByte(116);
        this.writeByte(0);

        var utf8Str = this.toUTF8Array(str);
        this.writeByte(utf8Str.length);

        for (var i = 0; i < utf8Str.length; i++) {
            this.writeByte(utf8Str[i]);
        }
    },

    toUTF8Array: function (str) {
        var utf8 = [];
        for (var i = 0; i < str.length; i++) {
            var charcode = str.charCodeAt(i);
            if (charcode < 0x80) utf8.push(charcode);
            else if (charcode < 0x800) {
                utf8.push(0xc0 | (charcode >> 6),
                    0x80 | (charcode & 0x3f));
            }
            else if (charcode < 0xd800 || charcode >= 0xe000) {
                utf8.push(0xe0 | (charcode >> 12),
                    0x80 | ((charcode >> 6) & 0x3f),
                    0x80 | (charcode & 0x3f));
            }
            else {
                // let's keep things simple and only handle chars up to U+FFFF...
                utf8.push(0xef, 0xbf, 0xbd); // U+FFFE "replacement character"
            }
        }
        return utf8;
    },

    /**
     * @deprecated need fix
     * @return {string}
     */
    writeString: function (str) {
        this.writeStringDirect(str);
        this.writeByte(0);
    },

    writeStringDirect: function (str) {
        for (var i = 0; i < str.length; i++) {
            this.writeByte(str.charCodeAt(i));
        }
    },

    appendBytes: function (bytes, offset, length) {
        var posOrg = this.position;
        this.position = this.length;
        this.writeBytes(bytes, offset, length);
        this.position = posOrg;
    },

    /**
     * @return {boolean}
     */
    readBoolean: function () {
        return this.readByte() == 1;
    },

    readByte: function () {
        if (this.bytesAvailable < 1)
            throw '遇到文件尾';
        var ret = this.dataView.getInt8(this.position, this.isLittleEndian);
        this.position++;
        return ret;
    },

    /**
     * 读取出length个字节放到bytes的offset处
     * @param {xinyou.ByteArray} bytes
     * @param {number} [offset = 0]
     * @param {number} [length = this.bytesAvailable]
     */
    readBytes: function (bytes, offset, length) {
        offset = offset || 0;
        length = length || this.bytesAvailable;
        bytes.position = offset;
        for (var i = 0; i < length; i++) {
            bytes.writeByte(this.readByte());
        }
    },

    readUnsignedByte: function () {
        if (this.bytesAvailable < 1)
            throw '遇到文件尾';
        var ret = this.dataView.getUint8(this.position, this.isLittleEndian);
        this.position++;
        return ret;
    },

    readShort: function () {
        if (this.bytesAvailable < 2)
            throw '遇到文件尾';
        var ret = this.dataView.getInt16(this.position, this.isLittleEndian);
        this.position += 2;
        return ret;
    },

    readUnsignedShort: function () {
        if (this.bytesAvailable < 2)
            throw '遇到文件尾';
        var ret = this.dataView.getUint16(this.position, this.isLittleEndian);
        this.position += 2;
        return ret;
    },

    readInt: function () {
        if (this.bytesAvailable < 4)
            throw '遇到文件尾';
        var ret = this.dataView.getInt32(this.position, this.isLittleEndian);
        this.position += 4;
        return ret;
    },

    readUnsignedInt: function () {
        if (this.bytesAvailable < 4)
            throw '遇到文件尾';
        var ret = this.dataView.getUint32(this.position, this.isLittleEndian);
        this.position += 4;
        return ret;
    },

    readLong: function () {
        if (this.bytesAvailable < 8)
            throw '遇到文件尾';
        var ret = [];
        for (var a = 0; a < 8; a++) {
            var cByte = this.dataView.getUint8(this.position, this.isLittleEndian);
            this.position++;
            ret.push(cByte);
        }
        return ret;
    },

    readLong64: function () {
        return ((this.readByte() & 255)) +
            ((this.readByte() & 255) * 0x100000000000000) +
            ((this.readByte() & 255) * 0x1000000000000) +
            ((this.readByte() & 255) * 0x10000000000) +
            ((this.readByte() & 255) * 0x100000000) +
            ((this.readByte() & 255) * 0x1000000) +
            ((this.readByte() & 255) * 0x10000) +
            ((this.readByte() & 255) * 0x100);
    },

    readULong64: function () {
        return (
            ((this.readUnsignedByte()) * 0x100000000000000) +
            ((this.readUnsignedByte()) * 0x1000000000000) +
            ((this.readUnsignedByte()) * 0x10000000000) +
            ((this.readUnsignedByte()) * 0x100000000) +
            ((this.readUnsignedByte()) * 0x1000000) +
            ((this.readUnsignedByte()) * 0x10000) +
            ((this.readUnsignedByte()) * 0x100) +
            ((this.readUnsignedByte()) * 0x1)
        );
    },

    readArrayToLong: function (array) {
        return (
            ((array[0]) * 0x100000000000000) +
            ((array[1]) * 0x1000000000000) +
            ((array[2]) * 0x10000000000) +
            ((array[3]) * 0x100000000) +
            ((array[4]) * 0x1000000) +
            ((array[5]) * 0x10000) +
            ((array[6]) * 0x100) +
            ((array[7]) * 0x1)
        );
    },

    /**
     * @param {number} [len=0] 读取长度
     * @return {string}
     */
    readString: function (len) {
        len = len || 0;
        var available = this.bytesAvailable;
        if (len > 0) available = Math.min(available, len);
        var c;
        var strEnd = false;
        var bytes = [];
        for (var i = 0; i < available; i++) {
            c = this.readUnsignedByte();
            if (c == 0) {
                strEnd = true;
                if (len == 0) break;
            }
            if (!strEnd)
                bytes[i] = c;
        }
        if (singleGame) {
            return iconv.decode(bytes, "cp936");
        }
        else {
            return xy.NativeExpand.convert(bytes, "utf-8", "gb2312");
        }
    },

    readMyString: function () {
        var firstByte = this.readByte();
        var length = 0;
        var bytes = [];
        if (firstByte == 112)
            return "";
        if (firstByte == 116) {
            this.readByte();
            length = this.readUnsignedByte();
        }

        for (var a = 0; a < length; a++) {
            bytes[a] = this.readByte();
        }

        return this.binayUtf8ToString(bytes);
    },

    readLongString: function () {
        var firstByte = this.readByte();
        var length = 0;
        var bytes = [];
        if (firstByte == 112)
            return "";
        if (firstByte == 116) {
            this.readByte();
            length = this.readUnsignedInt();
        }

        for (var a = 0; a < length; a++) {
            bytes[a] = this.readByte();
        }

        return this.binayUtf8ToString(bytes);
    },

    readFirstStr: function () {
        this.readByte();
        this.readShort();
        return this.readStr();
    },

    readStr: function () {
        var len = 0;

        var available = this.bytesAvailable;

        if (len > 0) available = Math.min(available, len);
        var c;
        var strEnd = false;
        var bytes = [];
        for (var i = 0; i < available; i++) {
            c = this.readUnsignedByte();
            if (c == 0 && bytes[i - 1] == 116) {
                strEnd = true;
                if (len == 0) break;

                bytes.splice(i - 1, 1)
            }
            if (!strEnd)
                bytes[i] = c;
        }

        return this.binayUtf8ToString(bytes);
    },

    binayUtf8ToString: function (buf, begin) {
        begin = begin | 0;
        var i = 0;
        var pos = 0;
        var str = "";
        var unicode = 0;
        var flag = 0;

        for (pos = begin; pos < buf.length;) {
            flag = buf[pos];

            if ((flag >>> 7) === 0) {
                str += String.fromCharCode(buf[pos]);

                pos += 1;
            } else if ((flag & 0xFC) === 0xFC) {
                unicode = (buf[pos] & 0x3) << 30;

                unicode |= (buf[pos + 1] & 0x3F) << 24;

                unicode |= (buf[pos + 2] & 0x3F) << 18;

                unicode |= (buf[pos + 3] & 0x3F) << 12;

                unicode |= (buf[pos + 4] & 0x3F) << 6;

                unicode |= (buf[pos + 5] & 0x3F);

                str += String.fromCharCode(unicode);

                pos += 6;
            } else if ((flag & 0xF8) === 0xF8) {
                unicode = (buf[pos] & 0x7) << 24;

                unicode |= (buf[pos + 1] & 0x3F) << 18;

                unicode |= (buf[pos + 2] & 0x3F) << 12;

                unicode |= (buf[pos + 3] & 0x3F) << 6;

                unicode |= (buf[pos + 4] & 0x3F);

                str += String.fromCharCode(unicode);

                pos += 5;
            } else if ((flag & 0xF0) === 0xF0) {
                unicode = (buf[pos] & 0xF) << 18;

                unicode |= (buf[pos + 1] & 0x3F) << 12;

                unicode |= (buf[pos + 2] & 0x3F) << 6;

                unicode |= (buf[pos + 3] & 0x3F);

                str += String.fromCharCode(unicode);

                pos += 4;
            } else if ((flag & 0xE0) === 0xE0) {
                unicode = (buf[pos] & 0x1F) << 12;

                unicode |= (buf[pos + 1] & 0x3F) << 6;

                unicode |= (buf[pos + 2] & 0x3F);

                str += String.fromCharCode(unicode);

                pos += 3;
            } else if ((flag & 0xC0) === 0xC0) { //110
                unicode = (buf[pos] & 0x3F) << 6;

                unicode |= (buf[pos + 1] & 0x3F);

                str += String.fromCharCode(unicode);

                pos += 2;
            } else {
                str += String.fromCharCode(buf[pos]);
                pos += 1;
            }
        }

        return str;
    },

    encodeUTF8: function (str) {
        var temp = "", rs = "";
        for (var i = 0, len = str.length; i < len; i++) {
            temp = str.charCodeAt(i).toString(16);
//    		cc.log("temp:" + temp);
            rs += "\\u" + new Array(5 - temp.length).join("0") + temp;
        }
        return rs;
    },

    decodeUTF8: function (str) {
        return str.replace(/(\\u)(\w{4}|\w{2})/gi, function ($0, $1, $2) {
            return String.fromCharCode(parseInt($2, 16));
        });
    },

    clear: function () {
        this.position = 0;
        this.length = 0;
    },

    destroy: function () {
        this.clear();
        this.dataView = null;
    },

    _bufferGetter: function () {
        return this.dataView.buffer.slice(0, this.length);
    },

    _bytesAvailableGetter: function () {
        return (this.length - this.position);
    },

    _updateLength: function () {
        if (this.position > this.length)
            this.length = this.position;
    }
});

var _p = xinyou.ByteArray.prototype;
cc.defineGetterSetter(_p, 'bytesAvailable', _p._bytesAvailableGetter);
cc.defineGetterSetter(_p, 'buffer', _p._bufferGetter);

/**
 * @class
 * @extends xinyou.ByteArray
 */
xinyou.Packet = xinyou.ByteArray.extend(/** @lends xinyou.Packet# */{

    msgLength: 0,
    checkCode: 0,
    v: NetConstant.VERSION,
    cmd: 0,

    /**
     * @param {xinyou.Packet} ba
     */
    readHead: function (ba) {
        this.msgLength = ba.readUnsignedShort();
        this.checkCode = ba.readUnsignedByte();
        this.v = ba.readByte();
        this.cmd = ba.readUnsignedInt();

        this.position = 0;
        this.writeShort(this.msgLength);
        this.writeByte(this.checkCode);
        this.writeByte(this.v);
        this.writeUnsignedInt(this.cmd);
    },

    clear: function () {
        this._super();
        this.msgLength = 0;
        this.checkCode = 0;
        this.v = NetConstant.VERSION;
        this.cmd = 0;
    }
});

/**
 * @class
 * @extends cc.Class
 */
var RoomManager = cc.Class.extend(/** @lends RoomManager */{

    kindID: 0,
    chairCount: 0,
    tableCount: 0,
    /**
     * 是否随机匹配类型房间
     * @type Boolean
     */
    isRandomAssignRoom: false,
    /**
     * 是否比赛房间
     * @type Boolean
     */
    isMatchRoom: false,
    /**
     * 是否是自动开始房间
     * @type Boolean
     */
    isAutoStartRoom: false,
    /**
     * 是否是选桌房间
     * @type Boolean
     */
    isSelectTableRoom: false,
    serverType: 0,
    name: '',
    desc: '',

    /**
     * @type {vo.Table[]}
     */
    _tableList: null,

    _userList: [],
    _tableUserInfo: {},

    /**
     * @param {netStruct.ServerInfo} msg
     */
    init: function (msg) {
        this.kindID = msg.kindID;
        this.chairCount = msg.chairCount;
        this.tableCount = msg.tableCount;
        this.serverType = msg.serverType;
        this.isRandomAssignRoom = Boolean(msg.serverType & EnumConstant.GAME_RAND_MATCHTYPE);
        this.isMatchRoom = Boolean(msg.serverType & EnumConstant.GAME_GENRE_MATCH);
        this.isAutoStartRoom = Boolean(msg.serverType & EnumConstant.GAME_GENRE_AUTO_START);
        if (!this.isRandomAssignRoom && !this.isMatchRoom && !this.isAutoStartRoom) {
            this.isSelectTableRoom = true;
        }
        this._tableList = [];
    },

    /**
     * @param {netStruct.GetTableListInfo} msg
     */
    initTableInfo: function (msg) {
        this._tableList = msg.tableList;
    },

    /**
     * @param {netStruct.TableStatus} msg
     */
    updateTableStatus: function (msg) {
        var table = this.getTable(msg.tableID);
        if (!table) {
            //throw '桌子状态更改时 桌子id不对 ' + msg.tableID;
            table = new vo.Table();
            table.id = msg.tableID;
            table.state = msg.state;
            table.started = msg.state == 1;
            this._tableList.push(table);
        }

        //如果桌子原来没有开始游戏 而且这次是开始游戏
        if (!table.started && (msg.state == 1)) {
            if (table.id == xinyou.gameFrame.me.wTableID) {
                var tableUser = this.getTableUser(table.id);
                if (tableUser) {
                    var i;
                    for (i = 0; i < tableUser.length; i++) {
                        /**
                         * @type vo.UserItem
                         */
                        var user = tableUser[i];
                        if (!user)
                            continue;

                        user.cbUserStatus = EnumConstant.US_PLAY;
                        xinyou.gameFrame.onUpdateUserItem(user);
                    }
                }
            }
        }

        table.locked = msg.havePassword;
        table.sitCondition = msg.haveSitCondition;
        table.sitConditionValue = msg.sitConditionValue;
        table.state = msg.state;
        table.started = msg.state == 1;
    },

    getTable: function (tableID) {
        var i;
        for (i = 0; i < this._tableList.length; i++) {
            var table = this._tableList[i];
            if (table.id == tableID) {
                return table;
            }
        }
        return null;
    },

    /**
     * 玩家进入房间
     * @param {Array} userList
     */
    addUser: function (userList) {
        var i;
        for (i = 0; i < userList.length; i++) {
            /**
             * @type vo.UserItem
             */
            var newUser = userList[i];
            /**
             * @type vo.UserItem
             */
            var oldUser = this.getUser(newUser.id);

            if (oldUser) {
                this.removeUser(oldUser.id);
            }
            this._userList.push(newUser);

            if (newUser.wTableID == XYConstant.INVALID_TABLE_ID)
                continue;

            this._userJoinTable(newUser, newUser.wTableID, newUser.wChairID);

        }

    },

    /**
     *
     * @param userID
     * @return {vo.UserItem}
     */
    getUser: function (userID) {
        var i;
        for (i = 0; i < this._userList.length; i++) {
            /**
             * @type vo.UserItem
             */
            var user = this._userList[i];
            if (user.id == userID) {
                return user;
            }
        }
        return null;
    },

    /**
     * @return {boolean}
     */
    removeUser: function (userID) {
        var i;
        for (i = 0; i < this._userList.length; i++) {
            /**
             * @type vo.UserItem
             */
            var user = this._userList[i];
            if (user.id == userID) {
                this._userList.splice(i, 1);

                this._removeUserFromTable(user.wTableID, user.wChairID);
                return true;
            }
        }
        return false;
    },

    /**
     * @param {netStruct.UserStatus} msg
     */
    updateUserStatus: function (msg) {
        /**
         * @type vo.UserItem
         */
        var user = this.getUser(msg.userID);
        if (!user) {
            xinyou.log('状态更改的用户 在列表里找不到 id: %s', msg.userID);
        }

        if (msg.status == EnumConstant.US_NULL) {
            this.removeUser(msg.userID);
        }
        else {
            var oldChairID = user.wChairID;
            var oldTableID = user.wTableID;
            var oldStatus = user.cbUserStatus;

            user.wNetDelay = msg.netDelay;
            user.cbUserStatus = msg.status;

            if ((oldStatus == EnumConstant.US_FREE) && (msg.status == EnumConstant.US_SIT)) {
                if (xinyou.gameFrame.me.id == user.id) {
                    if (xinyou.gameFrame.me.wTableID == XYConstant.INVALID_TABLE_ID) {
                        xinyou.netManager.sendGSInfoREQ();
                    }
                }
                user.wChairID = msg.chairID;
                user.wTableID = msg.tableID;
                this._userJoinTable(user, msg.tableID, msg.chairID);
                if (xinyou.gameFrame.isMeDataSended) {
                    this.dispatchUserJoinTable(user, msg.tableID, msg.chairID);
                }
            }
            else if (msg.status == EnumConstant.US_FREE) {
                this.dispatchLeaveTable(user, oldTableID, oldChairID);
                this._removeUserFromTable(oldTableID, user.id);
            }
            else if ((oldStatus == EnumConstant.US_OFFLINE) && (msg.status == EnumConstant.US_PLAY)) {
                if (xinyou.gameFrame.me.id == user.id) {
                    xinyou.netManager.sendGSInfoREQ();
                }
            }
            else {
                this.dispatchUpdateUserItem(user);
            }

            user.wChairID = msg.chairID;
            user.wTableID = msg.tableID;

        }
    },

    /**
     * @param {vo.UserItem} user
     * @param tableID
     * @param chairID
     * @private
     */
    _userJoinTable: function (user, tableID, chairID) {
        var users = this._tableUserInfo[tableID];
        if (!users) {
            this._tableUserInfo[tableID] = [];
        }
        this._tableUserInfo[tableID][chairID] = user;
        user.wTableID = tableID;
        user.wChairID = chairID;
    },

    /**
     * @param wTableID
     * @param userID
     * @return {boolean}
     * @private
     */
    _removeUserFromTable: function (wTableID, userID) {
        var users = this._tableUserInfo[wTableID];
        if (!users)
            return true;

        var i;
        for (i = 0; i < users.length; i++) {
            /**
             * @type vo.UserItem
             */
            var user = users[i];
            if (user && (user.id == userID)) {
                user.wTableID = XYConstant.INVALID_TABLE_ID;
                user.wChairID = XYConstant.INVALID_CHAIR_ID;
                users[i] = null;
                return true;
            }
        }
        return false;
    },

    /**
     * @param {netStruct.UserScoreMSG} msg
     */
    updateScore: function (msg) {
        /**
         * @type {vo.UserItem}
         */
        var user = this.getUser(msg.dwUserID);
        if (!user) {
            throw '积分更改的用户 在列表里找不到 id: ' + msg.dwUserID;
        }

        user.lCharm = msg.lCharm;
        user.lGameCount = msg.lGameCount;
        user.lGameCount_All = msg.lGameCount_All;
        user.lGameCount_Work = msg.lWorkCount;

        user.lGold = msg.userScore.lGold;
        user.lScore = msg.userScore.lScore;
        user.lWinCount = msg.userScore.lWinCount;
        user.lLostCount = msg.userScore.lLostCount;
        user.lDrawCount = msg.userScore.lDrawCount;
        user.lFleeCount = msg.userScore.lFleeCount;
        user.lExperience = msg.userScore.lExperience;

        this.dispatchUpdateUserItem(user);

    },

    /**
     * 加入桌子
     * @param {vo.UserItem} user
     * @param wTableID
     * @param wChairID
     */
    dispatchUserJoinTable: function (user, wTableID, wChairID) {
        xinyou.gameFrame.dispatchEvent(UIEvent.USER_JOIN_TABLE, {user: user, wTableID: wTableID, wChairID: wChairID});
        if (wTableID != xinyou.gameFrame.me.wTableID)
            return;

        if (user.id == xinyou.gameFrame.me.id) {
            /**
             * @type {vo.UserItem}
             */
            var meData = xinyou.gameFrame.me;
            xinyou.gameFrame.onSetMeUserData();
            xinyou.gameFrame.onEnterUserItem(meData);

            //==0 正常游戏状态  断线重连状态 同桌其他用户由 GS_OPTION 派发
//            if (xinyou.gameFrame.gameStatus == 0) {
//                var users = xinyou.roomManager.getTableUser(wTableID);
//                var i;
//                for (i = 0; i < users.length; i++) {
//                    /**
//                     * @type vo.UserItem
//                     */
//                    var userOnTable = users[i];
//                    if ((!userOnTable) || (userOnTable.id == meData.id))
//                        continue;
//
//                    xinyou.gameFrame.onEnterUserItem(userOnTable);
//                }
//            }

        }
        else {
            xinyou.gameFrame.onEnterUserItem(user);
        }

    },

    /**
     * 离开桌子
     * @param {vo.UserItem} user
     * @param wTableID
     * @param wChairID
     */
    dispatchLeaveTable: function (user, wTableID, wChairID) {
        xinyou.gameFrame.dispatchEvent(UIEvent.USER_LEAVE_TABLE, {user: user, wTableID: wTableID, wChairID: wChairID});

        var me = xinyou.gameFrame.me;
        if (wTableID == me.wTableID) {
            if (user.id == me.id) {

                var users = xinyou.roomManager.getTableUser(wTableID);
                var i;
                for (i = 0; i < users.length; i++) {
                    /**
                     * @type vo.UserItem
                     */
                    var userOnTable = users[i];
                    if (!userOnTable)
                        continue;

                    xinyou.gameFrame.onLeftUserItem(userOnTable);
                }
                this.isMeDataSended = false;
                this._isCoprocceor = false;

            } else if (user.wChairID != XYConstant.INVALID_CHAIR_ID) {
                xinyou.gameFrame.onLeftUserItem(user);
            }
        }
    },

    /**
     * 更新用户信息
     * @param {vo.UserItem} user
     */
    dispatchUpdateUserItem: function (user) {
        xinyou.gameFrame.dispatchEvent(UIEvent.UPDATE_USER_ITEM, user);
        var me = xinyou.gameFrame.me;
        if (!me) return;
        if ((me.wTableID != XYConstant.INVALID_TABLE_ID) && (me.wTableID == user.wTableID)) {
            xinyou.gameFrame.onUpdateUserItem(user);
        }
    },

    /**
     * @param wTableID
     * @return {Array}
     */
    getTableUser: function (wTableID) {
        if (wTableID < 0) return null;
        return this._tableUserInfo[wTableID];
    }
});

xinyou.gameFrame = new GameFrame();
xinyou.roomManager = new RoomManager();

/**
 * 修正web下不能formatstr
 */
xinyou.log = function (tag, log) {
	cc.log("tag:" + tag + ",log:" + log);
};

//xinyou.objectExist = function (o) {
//    if (!cc.sys.isNative) return o;
//    //哎 没办法 runtime 编译麻烦
//    if (singleGame) {
//        return o;
//    } else {
//        return xy.NativeExpand.nativeExist(o);
//    }
//};


xinyou.objectExist = function (obj) {
	if (!cc.sys.isNative) {
		return !!obj;
	}
	else {
		if (!obj) {
			return false;
		} else {
			try {
				if (!(obj instanceof cc.Node)) {
					return false;
				}
				else {
					obj.getChildren();
					return true;
				}
			}
			catch (e) {
				cc.log("e.message:" + e.message);
				return false;
			}
		}
	}
};

/**
 * Create a new object and copy all properties in an exist object to the new object
 * @function
 * @param {object|Array} obj The source object
 * @return {Array|object} The created object
 */
xinyou.clone = function (obj) {
    // Cloning is better if the new object is having the same prototype chain
    // as the copied obj (or otherwise, the cloned object is certainly going to
    // have a different hidden class). Play with C1/C2 of the
    // PerformanceVirtualMachineTests suite to see how this makes an impact
    // under extreme conditions.
    //
    // Object.create(Object.getPrototypeOf(obj)) doesn't work well because the
    // prototype lacks a link to the constructor (Carakan, V8) so the new
    // object wouldn't have the hidden class that's associated with the
    // constructor (also, for whatever reasons, utilizing
    // Object.create(Object.getPrototypeOf(obj)) + Object.defineProperty is even
    // slower than the original in V8). Therefore, we call the constructor, but
    // there is a big caveat - it is possible that the this.init() in the
    // constructor would throw with no argument. It is also possible that a
    // derived class forgets to set "constructor" on the prototype. We ignore
    // these possibities for and the ultimate solution is a standardized
    // Object.clone(<object>).
    var newObj = (obj.constructor) ? new obj.constructor : {};

    // Assuming that the constuctor above initialized all properies on obj, the
    // following keyed assignments won't turn newObj into dictionary mode
    // becasue they're not *appending new properties* but *assigning existing
    // ones* (note that appending indexed properties is another story). See
    // CCClass.js for a link to the devils when the assumption fails.
    for (var key in obj) {
        var copy = obj[key];
        // Beware that typeof null == "object" !
        if (((typeof copy) == "object") && copy && !(copy instanceof cc.Node)) {
            newObj[key] = xinyou.clone(copy);
        } else {
            newObj[key] = copy;
        }
    }
    return newObj;
};

/**
 * Check the obj whether is array or not
 * @param {*} obj
 * @returns {boolean}
 */
xinyou.isArray = function (obj) {
    return Object.prototype.toString.call(obj) == '[object Array]';
};
